#include "effectwidgetanimation.h"

EffectWidgetAnimation::EffectWidgetAnimation(QWidget *parent, DIRECTION dir):parent(parent)
  ,duration(0)
  ,width(60)
  ,height(60)
  ,gap(0)
  ,interval(30)
  ,dirtion(dir)
{
    widget = qobject_cast<Widget*>(parent);
    if (widget){
        this->parent = widget->getCentreWidget();
    }
    initStatus();
}

/**
 * @brief addButton     添加按钮
 * @param widget
 */
void EffectWidgetAnimation::addButton(QPushButton *widget)
{
    widget->resize(width,height);
    duration = interval*(allButton.count()+1);
    unsigned y=1;
    widget->setParent(parent);
    widget->setMouseTracking(true);
    for (int i=0; i<allButton.count(); ++i){
        y += height-3+gap;
        QObject::disconnect(allButton.at(i),SIGNAL(clicked(bool)), this, SLOT(btnClickedSlot()));
    }
    widget->move(x,y);
    allRect.append(QRect(x,y,width,height));
    widget->show();
    allButton.append(widget);
    for (QPushButton * b : allButton){
        b->setCheckable(true);
        QObject::connect(b,SIGNAL(clicked(bool)),this, SLOT(btnClickedSlot()));
    }
    setStyleSheets("QPushButton{ background-color:#33334C;border:none;color:white}QPushButton:hover{background-color:#D64A73}QPushButton:pressed{background-color:#D64A73}QPushButton:checked {background-color:#D64A73}");
}


/**
* @brief removeButton  删除一个button
* @param widget
*/
void EffectWidgetAnimation::removeButton(QPushButton *widget)
{
    if (widget){
        allButton.removeAll(widget);
        delete widget;
        widget = nullptr;
        sizeReset();
    }
    animationStart(currentStatus);
}

void EffectWidgetAnimation::removeButton(const QString &title)
{
    for (QPushButton* btn : allButton){
        if (title==btn->text()){
            removeButton(btn);
        }
    }
}

/**
 * @brief setStyleSheets        设置风格
 * @param style
 */
void EffectWidgetAnimation::setStyleSheets(const QString &style)
{
    for (QPushButton* button : allButton){
        button->setStyleSheet(style);
    }
}

/**
 * @brief anmation      属性动画
 * @param action
 */
void EffectWidgetAnimation::animationStart(ANIMATION action)
{
    if (timer->isActive()){
        return;
    }
    timer->setInterval(duration/2);
    setInitialze(action);
    if (ANIMATION::IN==action){
        currentStatus = IN;
        connect(timer, SIGNAL(timeout()),this,SLOT(timeoutSlotIn()));
        timer->start();
    }else if (ANIMATION::OUT==action){
        currentStatus = OUT;
        connect(timer, SIGNAL(timeout()),this,SLOT(timeoutSlotOut()));
        timer->start();
    }
    timer->start();
}

/**
 * @brief init      初始化
 */
void EffectWidgetAnimation::initStatus()
{
    timer = new QTimer(this);
    if (dirtion==LEFT_BORDER){
        x=1;
    }else if (dirtion==RIGHT_BORDER){
        x=parent->width()-width-1;
    }
    currentStatus = OUT;
    signalDeal();
}

void EffectWidgetAnimation::setButtonUnchecked()
{
    for (QPushButton * btn : allButton){
        btn->setChecked(false);
    }
}

void EffectWidgetAnimation::sizeReset()
{
    allRect.clear();
    int y = 1;
    for(QPushButton* button : allButton){
        button->resize(width,height);
        allRect.append(QRect(x,y,width,height));
         y += height-3+gap;
        button->move(x,y);
    }
}

QList<QPushButton *> EffectWidgetAnimation::getAllButton() const
{
    return allButton;
}

ANIMATION EffectWidgetAnimation::getCurrentStatus() const
{
    return currentStatus;
}

DIRECTION EffectWidgetAnimation::getDirtion() const
{
    return dirtion;
}

/**
 * @brief setDirtion        设置方向
 * @param value
 */
void EffectWidgetAnimation::setDirtion(const DIRECTION &value)
{
    dirtion = value;
    if (dirtion==RIGHT_BORDER){
        x = parent->width()-width-1;
    }else {
        x = 1;
    }
    sizeReset();
    signalDeal();
    animationStart(currentStatus);
}

int EffectWidgetAnimation::getInterval() const
{
    return interval;
}

void EffectWidgetAnimation::setInterval(int value)
{
    interval = value;
}

int EffectWidgetAnimation::getGap() const
{
    return gap;
}

void EffectWidgetAnimation::setGap(int value)
{
    gap = value;
    setDirtion(dirtion);
}

int EffectWidgetAnimation::getHeight() const
{
    return height;
}

void EffectWidgetAnimation::setHeight(int value)
{
    height = value;
    sizeReset();
}

int EffectWidgetAnimation::getWidth() const
{
    return width;
}

void EffectWidgetAnimation::setWidth(int value)
{
    width = value;
    sizeReset();
}

/**
 * @brief getDuration       动画时间
 */
unsigned EffectWidgetAnimation::getDuration() const
{
    return duration;
}

void EffectWidgetAnimation::setDuration(const unsigned &value)
{
    duration = value;
}

void EffectWidgetAnimation::setInitialze(const ANIMATION &action)
{
    if (action == ANIMATION::IN){
        for (QPushButton* b : allButton){
            b->resize(x,height);
        }
    }else {
        for (QPushButton* b : allButton){
            b->resize(width,height);
        }
    }
}

void EffectWidgetAnimation::timeoutSlotOut()
{
    static int i = 0;
    if (i>=allButton.count()){
        timer->stop();
        disconnect(timer, SIGNAL(timeout()),this,SLOT(timeoutSlotOut()));
        i = 0;
        return;
    }
    QPushButton* button = allButton.at(i++);
    QPropertyAnimation* a = new QPropertyAnimation(button, "geometry");
    a->setDuration(duration);
    QRect rect = allRect.at(i-1);
    if (dirtion == RIGHT_BORDER){
        rect.setX(parent->width()-width-1);
        rect.setWidth(width);
        rect.setHeight(height);
    }
    a->setStartValue(rect);
    rect.setWidth(0);
    if (dirtion == RIGHT_BORDER){
        rect.setX(parent->width());
        rect.setWidth(0);
    }
    a->setEndValue(rect);
    a->start();
}

void EffectWidgetAnimation::timeoutSlotIn()
{
    static int t = 0;
    if (t>=allButton.count()){
        timer->stop();
        disconnect(timer, SIGNAL(timeout()),this,SLOT(timeoutSlotIn()));
        t = 0;
        return;
    }
    QPushButton* button = allButton.at(t++);
    QPropertyAnimation* a = new QPropertyAnimation(button, "geometry");
    a->setDuration(duration);
    a->setStartValue(button->geometry());
    QRect rect = allRect.at(t-1);
    if (dirtion==RIGHT_BORDER){
        rect.setX(parent->width()-width-1);
        rect.setWidth(width);
        rect.setHeight(height);
    }
    a->setEndValue(rect);
    a->start();
}

void EffectWidgetAnimation::btnClickedSlot()
{
    setButtonUnchecked();
    animationStart(OUT);
}

void EffectWidgetAnimation::signalDeal()
{
    static bool connected=false;
    if (dirtion==RIGHT_BORDER && widget){
        connect(widget,SIGNAL(sizeChanged(QSize)),this,SLOT(animationStart()));
        connected=true;
    }else if (widget && connected){
        disconnect(widget,SIGNAL(sizeChanged(QSize)),this,SLOT(animationStart()));
    }
}
